Лабораторная работа 7 "Внешняя память"

Ранее вы реализовали процессор архитектуры RISC-V с оговоркой что он не поддерживает инструкции sh, sb, lh, lhu, lb, lbu. Данное ограничение имеет две причины:

  • вам нужен модуль, который будет определенным образом взаимодействовать с памятью в зависимости от конкретной инструкции загрузки или сохранения (модуль загрузки и сохранения, о котором будет рассказано на следующей лабораторной работе);
  • вам нужна внешняя память, которая будет способна делать то, что от нее запросит модуль загрузки и сохранения.

Реализации такой памяти и будет посвящена эта лабораторная работа.

Цель

Описать внешнюю память данных, полностью поддерживающую побайтовую адресацию.

Допуск к лабораторной работе

Для успешного выполнения лабораторной работы, вам необходимо:

Теория

В задании по реализации памяти инструкций лабораторной работы №3 байтовая адресация была описана следующим образом:

Байтовая адресация означает, что процессор способен обращаться к отдельным байтам в памяти (за каждым байтом памяти закреплен свой индивидуальный адрес).

Данное описание было дано не совсем корректным образом, чтобы в третьей лабораторной работе было более четкое понимание задания. В чем заключается некорректность? Процессор должен быть способен не только обращаться к отдельным байтам в памяти, но и обновлять в памяти любой отдельный байт, а также считывать отдельные байты.

Вопрос считывания отдельного байта будет решаться модулем загрузки и сохранения, данному модулю будет достаточно возвращать все слово, содержащее запрашиваемый байт как это было сделано в рамках лабораторной работы №3.

Нас интересует возможность памяти обновлять любой из байт в слове. Для этого используется специальный сигнал, который называется byte_enable_i. Разрядность этого сигнала равна числу байт в ячейке памяти (в данном случае разрядность byte_enable_i составляет 4). Вы можете представить byte_enable_i, как 4 провода, каждый из которых является сигналом разрешения записи для 8-ми D-триггеров, формирующих соответствующий этому проводу байт.

При этом не стоит забывать о том, что записью управляет еще и сигнал write_enable_i, определяющий режим работы памяти: запись или чтение.

Таким образом, для каждого байта addr_i / 4-ой ячейки памяти:

если write_enable_i равен единице и соответствующий этому байту бит сигнала byte_enable_i, то в данный байт памяти записывается соответствующий байт сигнала write_data_i.

При этом значение byte_enable_i может быть любым: если byte_enable_i == 4'b1001 (при write_enable == 1'b1), то данные должны быть записаны в старший и младший байты addr_i / 4-ой ячейки памяти.

Задание

Реализовать память данных с поддержкой обновления отдельных байт в выбранной ячейке памяти. Прототип модуля следующий (обратите внимание что название модуля отличается от названия памяти данных из третьей лабораторной работы — так мы сможем различать их):

module ext_mem(
  input  logic        clk_i,
  input  logic        mem_req_i,
  input  logic        write_enable_i,
  input  logic [ 3:0] byte_enable_i,
  input  logic [31:0] addr_i,
  input  logic [31:0] write_data_i,
  output logic [31:0] read_data_o,
  output logic        ready_o
);

Как и память данных из лабораторной работы №3, память данных в данной лабораторной состоит из 4096-и 32-разрядных ячеек и обладает портом синхронного чтения, обновляющим данные только по запросу на чтение (mem_req_i & !write_enable_i).

Иными словами, логика реализации порта на чтение повторяет логику памяти данных лабораторной работы №3 (можно скопировать эту логику).

Если mem_req_i == 1 и write_enable_i == 1 (т.е. если происходит запрос на запись в память), то необходимо обновить данные в тех байтах addr_i / 4-ой ячейки памяти, которые соответствуют единичным битам сигнала byte_enable_i.

Сигнал ready_o тождественно равен единице.

Порядок выполнения работы

  1. Внимательно ознакомьтесь с заданием. В случае возникновения вопросов, проконсультируйтесь с преподавателем.
  2. Реализуйте память данных. Для этого:
    1. В Design Sources проекта создайте SystemVerilog-файл ext_mem.sv.
    2. Опишите в нем модуль памяти данных с таким же именем и портами, как указано в задании.
      1. Данный модуль будет очень похож на память данных из лабораторной работы №3 (в частности, логика порта на чтение будет в точности повторять логику той памяти данных).
      2. Отличие заключается в двух новых сигналах ready_o и byte_enable_i.
        1. Сигнал ready_o тождественно равен единице.
        2. Сигнал byte_enable_i используется в качестве сигнала, разрешающего запись (в случае операции записи) в конкретный байт ячейки памяти.
    3. После описания памяти данных, её необходимо проверить с помощью тестового окружения.
      1. Тестовое окружение находится здесь.
      2. Для запуска симуляции воспользуйтесь этой инструкцией.
      3. Перед запуском симуляции убедитесь, что в качестве top-level модуля выбран корректный (tb_ext_mem).
      4. Во время симуляции, вы должны прожать "Run All" и убедиться, что в логе есть сообщение о завершении теста!